#include <iostream>
#include <vector>
#include <queue>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <atomic>
#include <functional>
#include <chrono>
using namespace std;

class ThreadPool {
public:
    typedef function<void()> Task;

    ThreadPool();
    ~ThreadPool();

    void setMaxTaskQueueSize(int size);  // 设置最大任务队列大小
    void start(int lowNum, int highNum);  // 设置最小和最大线程数量
    void setThreadIdleTime(int time);  // 设置线程空闲时间（秒）
    void stop();

    void pushTask(Task fn);
    int getCurrentThreadCount();
    void workerThread();
    void adjustThreads();

private:
    vector<thread> threads;
    queue<Task> tasks;
    mutex tasksMutex;
    condition_variable condVar;
    atomic<bool> running;
    int minThreads;
    int maxThreads;
    int maxTaskQueueSize;
    int threadIdleTime;
    atomic<int> idleThreads;
    atomic<int> activeThreads;
    condition_variable cv;
    mutex mtx;
};

ThreadPool::ThreadPool() {
    running = false;
    minThreads = 0;
    maxThreads = 0;
    maxTaskQueueSize = 0;
    threadIdleTime = 0;
    idleThreads = 0;
    activeThreads = 0;
}

ThreadPool::~ThreadPool() {
    stop();
}

void ThreadPool::setMaxTaskQueueSize(int size) {
    maxTaskQueueSize = size;
}

void ThreadPool::start(int lowNum, int highNum) {
    minThreads = lowNum;
    maxThreads = highNum;
    running = true;

    for (int i = 0; i < minThreads; i++) {
        threads.emplace_back(&ThreadPool::workerThread, this);
        activeThreads++;
    }

    thread(&ThreadPool::adjustThreads, this).detach();
}

void ThreadPool::setThreadIdleTime(int time) {
    threadIdleTime = time;
}

void ThreadPool::stop() {
    {
        lock_guard<mutex> lock(tasksMutex);
        running = false;
    }
    condVar.notify_all();
    cv.notify_all();

    for (thread& thread : threads) {
        if (thread.joinable()) {
            thread.join();
        }
    }
    threads.clear();
}

void ThreadPool::pushTask(Task fn) {
    unique_lock<mutex> lock(tasksMutex);
    if (tasks.size() < maxTaskQueueSize) {
        tasks.push(move(fn));
        condVar.notify_one();
    }
}

int ThreadPool::getCurrentThreadCount() {
    return threads.size();
}

void ThreadPool::workerThread() {
    while (running) {
        Task task;
        {
            unique_lock<mutex> lock(tasksMutex);
            condVar.wait(lock, [this] { return !tasks.empty() || !running; });
            if (!running && tasks.empty()) return;

            task = move(tasks.front());
            tasks.pop();
        }
        task();

        {
            lock_guard<mutex> lock(mtx);
            idleThreads++;
            activeThreads--;
            cv.notify_one();
        }
    }
}

void ThreadPool::adjustThreads() {
    while (running) {
        unique_lock<mutex> lock(mtx);
        cv.wait_for(lock, chrono::seconds(threadIdleTime), [this] {
            return !running || idleThreads > minThreads;
            });

        if (!running) return;

        if (idleThreads > minThreads) {
            int toRemove = idleThreads - minThreads;
            for (int i = 0; i < toRemove && activeThreads > minThreads; i++) {
                activeThreads--;
                idleThreads--;
                threads.pop_back();
            }
        }
        else {
            // 当空闲线程数小于等于最小线程数时，将线程池水位调整为 1
            int currentThreadCount = threads.size();
            if (currentThreadCount > 1) {
                int toRemove = currentThreadCount - 1;
                for (int i = 0; i < toRemove; i++) {
                    activeThreads--;
                    idleThreads--; // 调整空闲线程计数
                    threads.pop_back();
                }
            }
        }
    }
}

void testTask(int id) {
    cout << "任务 " << id << " 正在执行。" << endl;
    this_thread::sleep_for(chrono::seconds(1));
}

int main() {
    ThreadPool pool;
    pool.setMaxTaskQueueSize(25);
    pool.start(1, 10); // 设置最小线程数为 1，最大线程数为 10
    pool.setThreadIdleTime(10); // 设置线程空闲时间为 10 秒

    cout << "测试案例：线程池已启动。" << endl;
    for (int i = 1; i <= 20; i++) {
        pool.pushTask([i] { testTask(i); });
    }
    cout << "测试案例：已向线程池添加了 20 个任务。" << endl;

    this_thread::sleep_for(chrono::seconds(30));
    cout << "测试案例：经过 30 秒，线程池空闲时间超过设定时间，线程池当前水位为：" << pool.getCurrentThreadCount() << endl;

    pool.stop();

    return 0;
}
